/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.web.misc.license;

import java.math.BigInteger;
import java.util.Date;

public class LicenseDecoder {
    private static final BigInteger PUBLIC_MOD = new BigInteger("86f71688cdd2612ca117d1f54bdae029", 16);
    private static final BigInteger PUBLIC_EXP = new BigInteger("10001", 16);

    /**
     * 去掉了 idea 中对 2.0, 2.5, 3.x 的解码
     *
     * @param username
     * @param key
     * @return
     * @throws InvalidLicenseException
     */
    public static LicenseInfo decodeLicenseKey(String username, String key) throws InvalidLicenseException {
        LicenseInfo licenseInfo = new LicenseInfo();
        licenseInfo.username = username;

        int i = 0;
        for (int j = 0; j < key.length(); j++) {
            if ('-' == key.charAt(j)) i++;
        }

        if ((i != 5) && (i != 4)) {
            throw new InvalidLicenseException();
        }

        if (i == 5) {
            int n = key.indexOf('-');
            try {
                licenseInfo.customerId = Integer.parseInt(key.substring(0, n));
                key = key.substring(n + 1);
            } catch (NumberFormatException localNumberFormatException) {
                throw new InvalidLicenseException();
            }
        } else {
            licenseInfo.customerId = -1;
        }

        BigInteger license = LicenseUtil.decodeGroups(key).modPow(PUBLIC_EXP, PUBLIC_MOD);
        byte[] bytes = license.toByteArray();
        if (bytes.length != 12) {
            if (bytes.length == 13) {
                if (bytes[0] == 0) {
                    byte[] arrayOfByte = new byte[12];
                    System.arraycopy(bytes, 1, arrayOfByte, 0, 12);
                    bytes = arrayOfByte;
                } else {
                    throw new InvalidLicenseException();
                }
            } else if (bytes.length < 12) {
                byte[] arrayOfByte = new byte[12];
                System.arraycopy(bytes, 0, arrayOfByte, 12 - bytes.length, bytes.length);
                bytes = arrayOfByte;
            } else {
                throw new InvalidLicenseException();
            }
        }

        if (username != null) {
            int checksum = LicenseUtil.calculateCRC32(username, licenseInfo.customerId, bytes);
            if (bytes[10] != (byte) (checksum & 0xFF)) {
                throw new InvalidLicenseException();
            }
            if (bytes[11] != (byte) (checksum >> 8 & 0xFF)) {
                throw new InvalidLicenseException();
            }
        }

        licenseInfo.licenseId = (bytes[0] >> 4);
        licenseInfo.productId = (bytes[0] & 0xF);
        licenseInfo.majorVersion = bytes[1] & 0xF;
        licenseInfo.minorVersion = (bytes[1] >> 4) & 0xF;

        // 获取生成时间
        long genrationDate = (bytes[2] & 0xFFL) + ((bytes[3] & 0xFF) << 8) + ((bytes[4] & 0xFF) << 16) + ((bytes[5] & 0xFF) << 24) << 16;
        licenseInfo.generationDate = new Date(genrationDate);

        // 计算过期时间
        int days = (bytes[6] & 0xFF) + ((bytes[7] & 0xFF) << 8);
        if (days != 0) {
            licenseInfo.expirationDate = new Date(genrationDate + days * 24L * 60L * 60L * 1000L);
        }

        return licenseInfo;
    }


    public static void main(String[] args) throws InvalidLicenseException {
        BigInteger e = new BigInteger("10001", 16);
        System.out.println(e.toString());
        LicenseInfo licenseInfo = decodeLicenseKey("Vacoor", "24809-26ZH8-3ZTY0-R1A5O-PA412-VYRS1");
        System.out.println(licenseInfo);
    }
}